package org.nanotek.persistence.jpa.base.person.name;

import java.util.List;

import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SetAttribute;

import org.nanotek.base.person.name.NamePart;
import org.nanotek.base.person.name.NamePerson;
import org.nanotek.persistence.jpa.BrainzBaseDAO;

public class NamePersonDAO<T extends NamePerson> extends BrainzBaseDAO<T>{

	public NamePersonDAO() {
	}

	public List<?> findByNamePartValue(String value) 
	{ 
//		/*
//		 * CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
//		   Root<Pet> pet = cq.from(Pet.class);
//		   cq.where(pet.get(Pet_.color).in("brown", "black"));
//		   np.get(att).in(new ArrayList<String>(Arrays.asList(new String[]{value})))
//		   like(np.get(att),new StringBuilder().append("*").append(value).append("*").toString())
//		 */
//		CriteriaQuery<NamePerson> cq = getCriteriaQuery(NamePerson.class);
//		Metamodel m = entityManager.getMetamodel();
//		EntityType<NamePerson> etNP_ = m.entity(NamePerson.class);
//		Root<NamePerson> np = cq.from(etNP_);
//		SetAttribute<NamePerson,NamePart> att =(SetAttribute<NamePerson, NamePart>) etNP_.getAttribute("name");
//		Join<NamePerson,NamePart> join = np.join(att);
////		Fetch <NamePerson,NamePart> fetch = join.fetch("name");
////		new ArrayList<String>(Arrays.asList(new String[]{value})))
//		cq.where(
//		new Predicate[]{		
//				join.in(new NamePart[]{new NamePart(new String(value))})
//			}
//		);
////		cq.where(join.isNotNull());
//		TypedQuery<NamePerson> query = entityManager.createQuery(cq);
//		
		String jpql = "Select c from NamePerson c  inner join c.name d  where d.value in (:value)";
		Query query = entityManager.createQuery(jpql).setParameter("value", value);
		return query.getResultList();
	}
	
	public List<?> findByName(NamePart value) 
	{ 
		CriteriaQuery<T> cq = getCriteriaQuery();
		Metamodel m = entityManager.getMetamodel();
		EntityType<NamePerson> etNP_ = m.entity(NamePerson.class);
		Root<NamePerson> np = cq.from(etNP_);
		SetAttribute<NamePerson,NamePart> att = (SetAttribute<NamePerson, NamePart>) etNP_.getAttribute("name");
		Join<NamePerson,NamePart> join = np.join(att);
//		Fetch <NamePerson,NamePart> fetch = join.fetch("name");
//		new ArrayList<String>(Arrays.asList(new String[]{value})))
		cq.where(
				new Predicate[]{		
						join.in(new Object[]{value})
					}
		);
		TypedQuery<T> query = entityManager.createQuery(cq);
		return query.getResultList();
	}
	
	public List<?> findByName(String value) 
	{ 
//		CriteriaQuery<T> cq = getCriteriaQuery();
//		Metamodel m = entityManager.getMetamodel();
//		EntityType<NamePerson> etNP_ = m.entity(NamePerson.class);
//		Root<NamePerson> np = cq.from(etNP_);
//		EntityType<NamePerson> nprEt = m.entity(NamePerson.class);
//		Root<NamePart> nPR = getCriteriaQuery(NamePart.class).from(m.entity(NamePart.class));
//		SetAttribute<NamePerson,NamePart> att =(SetAttribute<NamePerson, NamePart>) etNP_.getAttribute("name");
//		Attribute<? super NamePerson, ?> ats = nprEt.getAttribute("value");//Here returns the Super Class LongBase
//		Join<NamePerson,NamePart> join = np.join(att);
////		Fetch <NamePerson,NamePart> fetch = join.fetch("name");
////		new ArrayList<String>(Arrays.asList(new String[]{value})))
//		cq.where(
//				new Predicate[]{		
//						join.in(new String[]{value})
//					}
//		);
//		TypedQuery<T> query = entityManager.createQuery(cq);
//		return query.getResultList();
		return null;
	}
}
